package com.ddtech.framework.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ddtech.exception.BadRequestException;
import com.ddtech.exception.EntityExistException;
import com.ddtech.exception.EntityNotFoundException;
import com.ddtech.framework.monitor.service.RedisService;
import com.ddtech.framework.system.model.SysDept;
import com.ddtech.framework.system.model.SysJob;
import com.ddtech.framework.system.model.SysRole;
import com.ddtech.framework.system.model.SysUser;
import com.ddtech.framework.system.model.bo.SysUserBo;
import com.ddtech.framework.system.model.bo.SysVrUserBo;
import com.ddtech.framework.system.model.vo.UserInfoVo;
import com.ddtech.framework.system.repository.DeptRepository;
import com.ddtech.framework.system.repository.JobRepository;
import com.ddtech.framework.system.repository.RoleRepository;
import com.ddtech.framework.system.repository.UserRepository;
import com.ddtech.framework.system.service.UserService;
import com.ddtech.framework.system.service.dto.UserDTO;
import com.ddtech.framework.system.service.dto.UserQueryCriteria;
import com.ddtech.framework.system.service.dto.VrUserDTO;
import com.ddtech.framework.system.service.mapper.UserMapper;
import com.ddtech.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Apache License
 * @date 2018-11-23
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private JobRepository jobRepository;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisService redisService;

    @Value("${file.framework}")
    private String frameworkPath;

    @Value("${dir.framework}")
    private String frameworkDir;

    @Value("${file.path}")
    private String filePath;


    @Override
    public Object queryAll(UserQueryCriteria criteria, Pageable pageable) {
        Page<SysUser> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(userMapper::toDto));
    }

    @Override
    public Object queryUserAll(UserQueryCriteria criteria, Pageable pageable) {
        Page<SysUser> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        List<VrUserDTO> userList= page.getContent().stream().
                map(item -> new VrUserDTO(item.getId(),item.getUsername(),
                        item.getName(),item.getPhone(),item.getPassword(),
                        item.getGrade(),item.getStudentClass(),item.getPermissionCode(),item.getSex(),item.getStudentNumber()))
                .collect(Collectors.toList());
        return PageUtil.toPage(userList,page.getTotalElements());
    }

    @Override
    public Object findTransferUsers(UserQueryCriteria criteria) {
        List<SysUser> deptUser = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
        JSONArray userJsonArray = new JSONArray();
        deptUser.forEach(sysUser -> {
            boolean contains = true;
            if (!StringUtils.isBlank(criteria.getRoleFlag())) {
                contains = sysUser.getRoles().stream().map(sysRole -> sysRole.getCode()).collect(Collectors.toList()).contains(criteria.getRoleFlag());
            }
            if (contains) {
                JSONObject userJsonObject = new JSONObject();
                userJsonObject.put("key", sysUser.getUsername());
                userJsonObject.put("id", sysUser.getId());
                userJsonObject.put("label", sysUser.getName());
                userJsonArray.add(userJsonObject);
            }
        });
        return userJsonArray;
    }

    /***
     * description:用户导入
     * @param:  * @param deptId
     * @param file
     * @param passWord
     * @date: 2023-07-24
     * @return: boolean
     * @version v1.0
     * @author:wei_zhang(xiao)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean userImport(String deptId, MultipartFile file, String passWord) {
        SysDept dept= deptRepository.getOne(deptId);
        if(dept==null){
            throw new EntityNotFoundException(SysDept.class,"部门不存在！");
        }
        Set<SysRole> roles =new HashSet<>();
        SysRole role=roleRepository.getOne("16758489249852407822");
        if(role==null){
            throw new EntityNotFoundException(SysDept.class,"角色不存在！");
        }
        roles.add(role);
        List<SysUserBo> list;
        try {
            list = EasyExcel.read(file.getInputStream()).head(SysUserBo.class).sheet().headRowNumber(1).doReadSync();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadRequestException("导入失败！");
        }
        List<SysJob> jobList= jobRepository.findAll();
        for(SysUserBo sysUserBo : list){
            SysUser user =new SysUser();
            //user.setEmployeeNature(sysUserBo.getEmployeeNature());
            user.setDept(dept);
            user.setEnabled(true);
            user.setPassword(passWord);
            user.setName(sysUserBo.getName());
            user.setUsername(sysUserBo.getAccount());
            user.setEmail(sysUserBo.getEmail());
            user.setPhone(sysUserBo.getPhone());
            user.setRoles(roles);
            user.setEmail(user.getUsername().concat("@ynhd.cn"));
            String job=sysUserBo.getJob();
//            for(SysJob sysJob : jobList){
//                if(job.equals(sysJob.getName())){
//                    user.setJob(sysJob);
//                    break;
//                }
//            }
            /**
             * 账号是否重复
             */
            if (userRepository.findByUsername(user.getUsername()) != null) {
                throw new EntityExistException(SysUser.class, "username", user.getUsername());
            }
           userRepository.save(user);
        }
        return true;
    }

    @Override
    public boolean vrUserImport(List<SysVrUserBo> list) {
        for(SysVrUserBo sysVrUserBo : list){
            Set<SysRole> roles =new HashSet<>();
            SysRole sysRole =new SysRole();
            String code=sysVrUserBo.getPermissionCode();
            if(code.equals("老师")){
                sysRole.setId("ff80808175ffa8a50175ffbb5fc50027");
            }else{
                sysRole.setId("16758489249852407822");
            }
            roles.add(sysRole);
            SysUser user =new SysUser();
            user.setEnabled(true);
            user.setPassword(sysVrUserBo.getPassWord());
            user.setName(sysVrUserBo.getName());
            user.setUsername(sysVrUserBo.getAccount());
            user.setPhone(sysVrUserBo.getPhone());
            user.setGrade(sysVrUserBo.getGrade());
            user.setStudentClass(sysVrUserBo.getStudentClass());
            user.setPermissionCode(code);
            user.setSex(sysVrUserBo.getSex());
            user.setStudentNumber(sysVrUserBo.getStudentNumber());
            user.setRoles(roles);
            /**
             * 账号是否重复
             */
            if (userRepository.findByUsername(user.getUsername()) != null) {
                throw new EntityExistException(SysUser.class, "username", user.getUsername());
            }
            userRepository.save(user);
        }
        return true;
    }

    /**
     * description:下载用户导入模板
     * @param:  * @param response
     * @date: 2023-07-25
     * @return: void
     * @version v1.0
     * @author:wei_zhang(xiao)
     */
    @Override
    public void downLoadUserTel(HttpServletResponse response) {
        String path = filePath+"tpl" + File.separator + "用户导入模板.xlsx";
        FileUtil.download(response, new File(path), "用户导入模板.xlsx");
    }

    @Override
    @Transactional
    public void updateAvatarV2(String url) {
        userRepository.updateAvatar(SecurityUtils.getUsername(), url);
    }

    @Override
    public void updateUserInfo(UserInfoVo userInfoVo) {
        Optional<SysUser> userOptional = userRepository.findById(SecurityUtils.getUserId());
        SysUser user = userOptional.get();
        BeanUtil.copyProperties(userInfoVo,user, CopyOptions.create().setIgnoreCase(true));
        userRepository.save(user);
    }

    @Override
    public UserDTO findById(String id) {
        Optional<SysUser> user = userRepository.findById(id);
        ValidationUtil.isNull(user, "User", "id", id);
        return userMapper.toDto(user.get());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO create(SysUser resources) {

        /**
         * 账号是否重复
         */
        if (userRepository.findByUsername(resources.getUsername()) != null) {
            throw new EntityExistException(SysUser.class, "username", resources.getUsername());
        }
        /**
         * 邮箱是重复
         */
//        if (userRepository.findByEmail(resources.getEmail()) != null) {
//            throw new EntityExistException(SysUser.class, "email", resources.getEmail());
//        }
        resources.setAvatar("");
        return userMapper.toDto(userRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUser resources) {
        Optional<SysUser> userOptional = userRepository.findById(resources.getId());
        ValidationUtil.isNull(userOptional, "User", "id", resources.getId());

        SysUser user = userOptional.get();

        SysUser user1 = userRepository.findByUsername(user.getUsername());
        //SysUser user2 = userRepository.findByEmail(user.getEmail());

        if (user1 != null && !user.getId().equals(user1.getId())) {
            throw new EntityExistException(SysUser.class, "username", resources.getUsername());
        }

//        if (user2 != null && !user.getId().equals(user2.getId())) {
//            throw new EntityExistException(SysUser.class, "email", resources.getEmail());
//        }

        // 如果用户的角色改变了，需要手动清理下缓存
        if (!resources.getRoles().equals(user.getRoles())) {
            String key = "role::loadPermissionByUser:" + user.getUsername();
            redisService.delete(key);
            key = "role::findByUsers_Id:" + user.getId();
            redisService.delete(key);
        }

        user.setUsername(resources.getUsername());
        user.setEmail(resources.getEmail());
        user.setEnabled(resources.getEnabled());
        user.setRoles(resources.getRoles());
        user.setDept(resources.getDept());
        user.setPhone(resources.getPhone());
        user.setName(resources.getName());
        user.setSex(resources.getSex());
        if(StringUtils.isNotEmpty(resources.getPassword())){
            user.setPassword(resources.getPassword());
        }
        user.setStudentNumber(resources.getStudentNumber());
        user.setGrade(resources.getGrade());
        user.setStudentClass(resources.getStudentClass());
        user.setPermissionCode(resources.getPermissionCode());
        userRepository.save(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        userRepository.deleteById(id);
    }

    @Override
    public UserDTO findByName(String userName) {
        SysUser user = null;
        if (ValidationUtil.isEmail(userName)) {
            user = userRepository.findByEmail(userName);
        } else {
            user = userRepository.findByUsername(userName);
        }
        if (user == null) {
            throw new BadRequestException("账号不存在");
        } else {
            return userMapper.toDto(user);
        }
    }


    @Override
    public SysUser findByAccount(String userName) {
        return userRepository.findByUsername(userName);
    }

    @Override
    public SysUser findByNickname(String userName) {
        return userRepository.findByName(userName);
    }

    @Override
    public SysUser findByEmail(String email) {
        return userRepository.findByEmail(email);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePass(String username, String pass) {
        return userRepository.updatePass(username, pass, new Date());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAvatar(MultipartFile multipartFile) {
        String avatar = "avatar";
        String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
        if (image.indexOf(suffix) != -1) {
            File file = FileUtil.upload(multipartFile, frameworkPath + avatar + File.separator);
            String url = "/file/" + frameworkDir + "/" + avatar + "/" + file.getName();
            userRepository.updateAvatar(SecurityUtils.getUsername(), url);
        } else {
            throw new BadRequestException("不支持的格式");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmail(String username, String email) {
        userRepository.updateEmail(username, email);
    }
}
